﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Net;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using System.Windows.Forms;

namespace Valuttakalkulator
{
    public partial class ValuttaForm : Form
    {
        private List<Valuta> valutaer = new List<Valuta>();
        private String fileName = AppDomain.CurrentDomain.BaseDirectory + "valuta.valuttaXml";
        private XDocument xmlDoc = null;
        private string oldText;
        public ValuttaForm()
        {
            InitializeComponent();
        }

        private void DownloadValutta()
        {
            WebClient webClient = new WebClient();
            try
            {
                if (File.Exists(fileName))
                {
                    if (File.Exists(fileName + "mid.valuttaXml"))
                        File.Delete(fileName + "mid.valuttaXml");
                    File.Move(fileName, fileName + "mid.valuttaXml");
                }
                webClient.DownloadFile("https://www.dnbnor.no/portalfront/datafiles/miscellaneous/csv/kursliste_ws.xml", fileName);
                if(File.Exists(fileName + "mid.valuttaXml"))
                    File.Delete(fileName + "mid.valuttaXml");
            }
            catch (Exception e)
            {
                try
                {
                    if (File.Exists(fileName + "mid.valuttaXml"))
                    {
                        File.Copy(fileName + "mid.valuttaXml", fileName);
                        File.Delete(fileName + "mid.valuttaXml");
                    }
                }
                catch
                {
                    MessageBox.Show("Noe gikk galt under lasting av valuttaer, og backupen er slettet. Programmet kan ikke kjøre før det klarer å laste ned valuttaer igjen.", "Feil", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Application.Exit();
                }
                DialogResult result = MessageBox.Show("En feil oppstod under forsøket på å laste ned valuttakursene.", "Feil under lasting av valuttakurser", MessageBoxButtons.AbortRetryIgnore, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button3);
                if (result == DialogResult.Abort)
                    Application.Exit();
                else if (result == DialogResult.Retry)
                {
                    DownloadValutta();
                    return;
                }
            }
        }

        private void LoadValutta()
        {
            try
            {
                xmlDoc = XDocument.Load(fileName);
                int unit;
                double value;
                IEnumerable<Valuta> valuttaer = from v in xmlDoc.Element("valuta").Elements("valutakurs")
                                                select new Valuta(String.Format("{0} ({1})", v.Element("land").Value, v.Element("kode").Value),
                                                    (int.TryParse(v.Element("enhet").Value, out unit) ? unit : 100),
                                                    (double.TryParse(v.Element("overforsel").Element("salg").Value.Replace(".", ","), out value) ? value : 100));
                valutaer.Clear();
                foreach (Valuta v in valuttaer)
                {
                    valutaer.Add(v);
                }
                UpdateValuttaer();
            }
            catch (Exception e)
            {
                MessageBox.Show("Kan ikke lese fra valutta-filen. Dette kan komme av flere årsaker, og den eneste løsningen kan være å starte datamaskinen på nytt.\nDet annbefales i førsteomgang å prøve å restarte programmet.", "Feil ved lesing av fil.", MessageBoxButtons.OK, MessageBoxIcon.Error);
                Application.Exit();
            }
        }

        private void UpdateValuttaer()
        {
            int selectedItem = ValutaComboBox.SelectedIndex;
            if (selectedItem < 0)
                selectedItem = 0;
            if (selectedItem >= valutaer.Count)
                selectedItem = valutaer.Count - 1;
            ValutaComboBox.Items.Clear();
            foreach (Valuta v in valutaer)
            {
                ValutaComboBox.Items.Add(v.Name);
            }
            ValutaComboBox.SelectedIndex = selectedItem;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DownloadValutta();
            LoadValutta();
        }

        private bool isDecimal(string test)
        {
            decimal result;
            return decimal.TryParse(test, out result);
        }

        private void decimalControl_Validated(object sender, EventArgs e)
        {

        }

        private void ValutaComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            kursTextBox.Text = valutaer[ValutaComboBox.SelectedIndex].Price.ToString();
            UpdateAll();
        }
        private void UpdateAll()
        {
            try
            {
                int antall = int.Parse(antallTextBox.Text);
                if (antall == 0)
                {
                    return;
                }
                double pris = double.Parse(prisTextBox.Text);
                double frakt1 = double.Parse(frakt1TextBox.Text);
                double frakt2 = double.Parse(frakt2TextBox.Text);
                double kurs = valutaer[ValutaComboBox.SelectedIndex].Price;
                int enhet = valutaer[ValutaComboBox.SelectedIndex].Unit;
                double NOK = (pris * antall * kurs) / enhet;
                NOKTextBox.Text = NOK.ToString();
                double mva = (NOK <= 200) ? 0.0 : NOK * 0.25;
                mvaTextBox.Text = mva.ToString();
                double frakt = ((frakt1 + ((antall - 1) * frakt2)) * kurs) / enhet;
                fraktTextBox.Text = frakt.ToString();
                int totalt = (int)Math.Ceiling(NOK + mva + frakt);
                totaltTextBox.Text = String.Format("{0},00", totalt.ToString());
                int perStk = (int)Math.Ceiling(((NOK + mva + frakt) / antall));
                perStkTextBox.Text = String.Format("{0},00", perStk.ToString());
            }
            catch
            {
                NOKTextBox.Text = (0).ToString();
                mvaTextBox.Text = (0).ToString();
                fraktTextBox.Text = (0).ToString();
                totaltTextBox.Text = (0).ToString();
                perStkTextBox.Text = (0).ToString();
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            this.TopMost = checkBox1.Checked;
        }

        private void control_Validation(object sender, EventArgs e)
        {
            control_Validation(sender, e, false);
        }

        private void control_Validation(object sender, EventArgs e, bool setText)
        {
            TextBox s = ((TextBox)sender);
            if (!setText)
            {
                if (String.IsNullOrEmpty(s.Text))
                {
                    if (!String.IsNullOrEmpty(oldText))
                    {
                        s.Text = oldText;
                    }
                    else
                    {
                        s.Text = "0";
                    }
                }
            }
            if (!isDecimal(s.Text))
            {
                Color c = Color.FromArgb(255, 200, 200);
                s.BackColor = c;
            }
            else
            {
                s.BackColor = Color.FromKnownColor(KnownColor.Window);
            }
            UpdateAll();
        }

        private void control_FocusEnter(object sender, EventArgs e)
        {
            oldText = ((TextBox)sender).Text;
            ((TextBox)sender).Text = "";
        }

        private void antallTextBox_KeyUp(object sender, KeyEventArgs e)
        {
            control_Validation(sender, e, true);
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            ValidateChildren();
            ActiveControl = null;
        }

        private void UpdateButton_Click(object sender, EventArgs e)
        {
            Form1_Load(sender, e);
        }
    }
}
